var FileCommand = require('./file_command.js');

function getNow() {
    var d = new Date();
    return d.getTime()/1000;
}

function P2PFileSession(im) {
    this.im = im;
    this.state = P2PFileSession.VOIP_ACCEPTING;

    this.fileName = "";
    this.fileSize = 0;
    this.fileMD5 = "";

    this.isPresent = false;//对方是否在线

    this.dialTimer = 0;
    this.pingTimer = 0;
    this.completeTimer = 0;
    this.DEBUG = false;
}

P2PFileSession.VOIP_LISTENING = 1;
P2PFileSession.VOIP_DIALING = 2;//呼叫对方
P2PFileSession.VOIP_CONNECTED = 3;//通话连接成功
P2PFileSession.VOIP_ACCEPTING = 4;//询问用户是否接听来电
P2PFileSession.VOIP_ACCEPTED = 5;//用户接听来电
P2PFileSession.VOIP_REFUSING = 6;//来电被拒
P2PFileSession.VOIP_REFUSED = 7;//(来/去)电已被拒

//end states
P2PFileSession.VOIP_HANGED_UP = 8;//通话被挂断
P2PFileSession.VOIP_SHUTDOWN = 9;//对方正在通话中连接被终止
P2PFileSession.VOIP_COMPLETED = 10;



P2PFileSession.prototype.dial = function() {
    this.state = P2PFileSession.VOIP_DIALING;

    this.dialBeginTimestamp = getNow();
    this.sendDial();

    var self = this;
    this.dialTimer = setInterval(function() {
        self.sendDial();
        var now = getNow();
        if (!self.isPresent && now - self.dialBeginTimestamp >= 10) {
            console.log("peer is't present, can't send online file");
            self.onOffline();
            self.clearDialTimer();
        } else if (now - self.dialBeginTimestamp >= 60) {
            self.onDialTimeout();
            self.clearDialTimer();
        }
    }, 1000);

    console.log("dial timer:", this.dialTimer);
};

P2PFileSession.prototype.ping = function() {
    var self = this;
    this.pingTimer = setInterval(function() {
        self.sendPing();
    }, 1000);
    this.sendPing();
}

P2PFileSession.prototype.accept = function() {
    this.state = P2PFileSession.VOIP_ACCEPTED;
    this.sendDialAccept();
};


P2PFileSession.prototype.refuse = function() {
    this.state = P2PFileSession.VOIP_REFUSED;
    this.sendDialRefuse();
};

//取消
P2PFileSession.prototype.hangUp = function() {
    if (this.state == P2PFileSession.VOIP_DIALING) {
        this.clearDialTimer();
        this.sendHangUp();
        this.state = P2PFileSession.VOIP_HANG_UP;
    } else if (this.state == P2PFileSession.VOIP_CONNECTED) {
        this.sendHangUp();
        this.state = P2PFileSession.VOIP_HANG_UP;

        this.clear();

    } else {
        console.log("invalid voip state:" + this.state);
    }
};

//接受完成
P2PFileSession.prototype.complete = function() {
    this.completeTimestamp = getNow();
    this.state = P2PFileSession.VOIP_COMPLETED;
    var self = this;
    this.completeTimer = setInterval(function() {
        self.sendCompleted();
        var now = getNow();
        if (now - self.completeTimestamp >= 100) {
            self.clear();
            self.onCompleted();
        }
    }, 1000);

    this.sendCompleted();
}

P2PFileSession.prototype.sendCommand = function(command) {
    var msg = {};
    msg.sender = this.uid;
    msg.receiver = this.peer;
    msg.content = JSON.stringify({file:command.toData()});
    if (this.DEBUG) {
        console.log("send rt message:", msg.content);
    }
    var r = this.im.sendRTMessage(msg);
    return r;
};

P2PFileSession.prototype.sendTalking = function(receiver) {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_TALKING;
    command.channelID = this.channelID;
    var msg = {};
    msg.sender = this.uid;
    msg.receiver = receiver;
    msg.content = JSON.stringify({file:command.toData()});
    this.im.sendRTMessage(msg);
};

P2PFileSession.prototype.sendPing = function() {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_PING;
    command.channelID = this.channelID;
    this.sendCommand(command);
};


P2PFileSession.prototype.sendDial = function() {
    console.log("send dial...");
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_DIAL;
    command.channelID = this.channelID;
    command.name = this.fileName;
    command.size = this.fileSize;
    this.sendCommand(command);
};

P2PFileSession.prototype.sendDialAccept = function(recveiver) {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_ACCEPT;
    command.channelID = this.channelID;
    this.sendCommand(command);
};


P2PFileSession.prototype.sendDialRefuse = function(receiver) {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_REFUSE;
    command.channelID = this.channelID;
    this.sendCommand(command);
};


P2PFileSession.prototype.sendConnected = function(receiver) {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_CONNECTED;
    command.channelID = this.channelID;
    this.sendCommand(command);
};

P2PFileSession.prototype.sendRefused = function(receiver) {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_REFUSED;
    command.channelID = this.channelID;
    this.sendCommand(command);
};

P2PFileSession.prototype.sendHangUp = function() {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_HANG_UP;
    command.channelID = this.channelID;
    this.sendCommand(command);
};


P2PFileSession.prototype.sendCompleted = function() {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_COMPLETED;
    command.channelID = this.channelID;
    this.sendCommand(command);
};

P2PFileSession.prototype.sendCompletedAck = function() {
    var command = new FileCommand();
    command.cmd = FileCommand.VOIP_COMMAND_COMPLETED_ACK;
    command.channelID = this.channelID;
    command.md5 = this.fileMD5;
    this.sendCommand(command);
};


//清空所有的定时器
P2PFileSession.prototype.clear = function() {
    if (this.pingTimer) {
        clearInterval(this.pingTimer);
        this.pingTimer = 0;
    }
    if (this.dialTimer) {
        clearInterval(this.dialTimer);
        this.dialTimer = 0;
    }
    if (this.completeTimer) {
        clearInterval(this.completeTimer);
        this.completeTimer = 0;
    }
}

P2PFileSession.prototype.clearDialTimer = function() {
    console.log("clear dial timer....:", this.dialTimer);
    if (this.dialTimer > 0) {
        console.log("clear dial timer");
        clearInterval(this.dialTimer);
        this.dialTimer = 0;
    }
};

P2PFileSession.prototype.handleFileMessage = function(obj, sender) {
    if (sender != this.peer) {
        this.sendTalking(sender);
        return;
    }

    var command = new FileCommand();
    command.fromData(obj);
    if (this.state == P2PFileSession.VOIP_DIALING) {
        if (command.cmd == FileCommand.VOIP_COMMAND_ACCEPT) {
            this.sendConnected();
            this.clearDialTimer();
            this.onConnected();
            this.state = P2PFileSession.VOIP_CONNECTED;
        } else if (command.cmd == FileCommand.VOIP_COMMAND_REFUSE) {
            this.sendRefused();
            this.clearDialTimer();
            this.onRemoteRefuse();
            this.state = P2PFileSession.VOIP_REFUSED;
        } else if (command.cmd == FileCommand.VOIP_COMMAND_PRESENT) {
            this.isPresent = true;
        } else if (command.cmd == FileCommand.VOIP_COMMAND_TALKING) {
            this.clearDialTimer();
            this.onTalking();
            this.state = P2PFileSession.VOIP_SHUTDOWN;
        }
    } else if (this.state == P2PFileSession.VOIP_ACCEPTING) {
        if (command.cmd == FileCommand.VOIP_COMMAND_HANG_UP) {
            this.clear();
            this.state = P2PFileSession.VOIP_HANGED_UP;
            this.onRemoteHangUp();
        } else if (command.cmd == FileCommand.VOIP_COMMAND_DIAL) {
            this.accept();
        }
    } else if (this.state == P2PFileSession.VOIP_ACCEPTED) {
        if (command.cmd == FileCommand.VOIP_COMMAND_CONNECTED) {
            this.onConnected();
            this.state = P2PFileSession.VOIP_CONNECTED;
        } else if (command.cmd == FileCommand.VOIP_COMMAND_DIAL) {
            this.sendDialAccept();
        }
    } else if (this.state == P2PFileSession.VOIP_CONNECTED) {
        if (command.cmd == FileCommand.VOIP_COMMAND_HANG_UP) {
            //中止发送或接受文件
            this.state = P2PFileSession.VOIP_HANGED_UP;
            this.clear();
            this.onRemoteHangUp();
        } else if (command.cmd == FileCommand.VOIP_COMMAND_COMPLETED) {
            //接收方发来消息，表示接受完成
            //在completedack中需要包括fileMD5, 这样接收方才能校验文件
            if (this.fileMD5) {
                this.sendCompletedAck();
                this.clear();
                this.state = P2PFileSession.VOIP_COMPLETED;
                this.onCompleted();
            }
        }
    } else if (this.state == P2PFileSession.VOIP_COMPLETED) {
        if (command.cmd == FileCommand.VOIP_COMMAND_COMPLETED_ACK) {
            //文件发送方发来的消息
            this.fileMD5 = command.md5;
            this.clear();
            this.onCompleted();
        }
    }
};


P2PFileSession.prototype.onRemoteRefuse = function() {
    console.log("on refuse");
};

P2PFileSession.prototype.onRemoteHangUp = function() {
    console.log("on remote hangup");
};

P2PFileSession.prototype.onTalking = function() {
    console.log("on talking");
};

P2PFileSession.prototype.onDialTimeout = function() {
    console.log("dial timeout");
};

P2PFileSession.prototype.onOffline = function() {
    console.log("peer offline");
};

P2PFileSession.prototype.onConnected = function() {
    console.log("on connected");
};

P2PFileSession.prototype.onCompleted = function() {
    console.log("on completed");
}

console.log("p2pfile session...");

module.exports = P2PFileSession;
